package it.antonio.ilpizze.db.core;

import it.antonio.ilpizze.db.HashIndex;
import it.antonio.ilpizze.db.Id;
import it.antonio.ilpizze.db.core.LockManager;
import it.antonio.ilpizze.db.core.StatusManager;
import it.antonio.ilpizze.db.core.TransactionManager;
import it.antonio.ilpizze.db.index.hash.HashTable;
import it.antonio.ilpizze.db.io.IOFile;

public class FileHashIndex<K> implements HashIndex<K>{
	
	private HashTable<K, Id> table;
	private TransactionManager txManager;
	private StatusManager statusManager;
	private LockManager lockManager;
	
	public FileHashIndex(HashTable<K, Id> table, TransactionManager txManager, StatusManager statusManager,  LockManager lockManager) {
		this.table = table;
		this.txManager = txManager;
		this.statusManager = statusManager;
		this.lockManager = lockManager;
	}

	public Id get(final K key) {
		checkReadStatus();
		lockManager.checkMultiThreadingRead();
		Id id = table.get(key);
		return id;
	}

	public void remove(final K key) {
		checkWriteStatus();
		lockManager.checkMultiThreadingWrite();
		
		final Id id = table.remove(key);
		
		if(txManager.autoCommit() == false){
			txManager.add(new TransactionUnit() {
				
				@Override
				public void commit() {
					
				}
				
				@Override
				public void rollback() {
					if(id!=null){
						table.put(key, id);
					}
				}
				
				@Override
				public void log(IOFile txLog) {
					
				}
				
				
			});
		}
	}

	public void put(final K key, Id id) {
		checkWriteStatus();
		lockManager.checkMultiThreadingWrite();
		
		table.put(key, id);
		
		if(txManager.autoCommit() == false){
			txManager.add(new TransactionUnit() {
				
				@Override
				public void commit() {
					
				}
				
				@Override
				public void rollback() {
					table.remove(key);
				}
				
				@Override
				public void log(IOFile txLog) {
					
				}
				
				
			});
		}
	}

	private void checkReadStatus(){
		if(txManager.autoCommit() == false) {
			statusManager.checkStatus(Status.OPEN, Status.TRANSACTION);
		} else {
			statusManager.checkStatus(Status.OPEN);
		}
	}
	
	private void checkWriteStatus(){
		if(txManager.autoCommit() == false) {
			statusManager.checkStatus(Status.TRANSACTION);
		} else {
			statusManager.checkStatus(Status.OPEN);
		}
	}
}
